home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Archive / Graphics / QuickDraw GX / GX->PostScript Sample / GXToPostScript / I⁄O Utilities / dprintf.c next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  6.6 KB  |  233 lines  |  [TEXT/MPS ]

  1. /*
  2.      File:        dprintf.c
  3.  
  4.      Contains:    QuickDraw GX to PostScript conversion code.
  5.  
  6.      Version:    Technology:    Quickdraw GX 1.1.x
  7.       
  8.      Copyright:    © 1994-1997 by Apple Computer, Inc., all rights reserved.
  9. */
  10.  
  11. #include <stdio.h>
  12. #include <stdarg.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15.  
  16. #ifndef __TYPES__
  17.     #include <Types.h>
  18. #endif
  19.  
  20. enum {
  21.     kMaxDebugStringLength                     = 255
  22. };
  23.  
  24.  
  25. /*
  26.      File:        dprintf.c
  27.  
  28.      Contains:    QuickDraw GX to PostScript conversion code.
  29.  
  30.      Version:    Technology:    Quickdraw GX 1.1.x
  31.       
  32.      Copyright:    © 1994-1997 by Apple Computer, Inc., all rights reserved.
  33.  
  34.     You may incorporate this code into your applications without
  35.     restriction, though the code has been provided "AS IS" and the
  36.     responsibility for its operation is 100% yours.  However, what you are
  37.     not permitted to do is to redistribute the source as "Apple Sample
  38.     Code" after having made changes. If you're going to re-distribute the
  39.     source, we require that you make it clear in the source that the code
  40.     was descended from Apple Sample Code, but that you've made changes. 
  41. */
  42.  
  43. /*    ----------------------------------------------------------------------------------------
  44.     Routine:    dprintf
  45.     
  46.     Purpose:    dprintf is equivelant to the Standard C library routine printf,
  47.                 except that the resulting text is sent to the debugger in a DebugStr
  48.                 call. This is especially useful in conjunction with Exceptions.h,
  49.                 which requires an externally declared dprintf for require and check
  50.                 to work at debugging levels other than DEBUGMIN.
  51.     ----------------------------------------------------------------------------------------    */
  52.  
  53. #include <GXExceptions.h>
  54. void dprintf(StringPtr debuggerCommand, char formatString[], ...)
  55. {
  56.     va_list             argumentList;
  57.     int                    stringLength = 0;
  58.     char                debugString[kMaxDebugStringLength + 2],
  59.                         parameterString[kMaxDebugStringLength + 1],
  60.                         parameterFormatString[kMaxDebugStringLength],
  61.                         *currentParameterFormatString;
  62.     char                *currentChar, currentCharValue;
  63.     int                    paramStringLength, combinedNewLength;
  64.     int                    paramTruncated = 0;
  65.     int                    argsWritten = 0;
  66.     int                    stillFormatString, badParameter;
  67.  
  68.     int                    iValue;
  69.     char                *sValue;
  70.     double                dValue;
  71.     void                *pValue;
  72.     int                    *iArgCount;
  73.  
  74. #pragma unused(debuggerCommand)
  75.  
  76.     va_start(argumentList, formatString);
  77.  
  78.     for (currentChar = formatString; *currentChar && (stringLength < kMaxDebugStringLength); currentChar++) {
  79.         
  80.         currentCharValue = *currentChar;
  81.         
  82.         /*    If the current format character is not a meta-character indicator, then just add the 
  83.             character to the debug string as-is and go on to the next character in the format
  84.             string. */
  85.         
  86.         if (currentCharValue != '%') {
  87.             debugString[++stringLength] = *currentChar;
  88.             continue;
  89.         }
  90.  
  91.         /*    Otherwise we have a meta character %.  Depending on the characters following the %,
  92.             we have to create a parameter format string to pass to sprintf.  The exact
  93.             semantics of this are defined in K & R. */
  94.  
  95.         /*    First add the meta character itself. */
  96.  
  97.         currentParameterFormatString = parameterFormatString;
  98.         *currentParameterFormatString++ = '%';
  99.  
  100.         stillFormatString = true;
  101.         badParameter = false;
  102.  
  103.         while (stillFormatString) {
  104.         
  105.             currentCharValue = *++currentChar;
  106.         
  107.             switch (currentCharValue) {
  108.             
  109.                 /*    Valid embedded characters for the meta-string. */
  110.             
  111.                 case 'h': case 'H': case 'l': case 'L':
  112.                 case '+': case '-': case ' ': case '#': case '.':
  113.                 case '0': case '1': case '2': case '3': case '4': 
  114.                 case '5': case '6': case '7': case '8': case '9':
  115.                     *currentParameterFormatString++ = currentCharValue;
  116.                     break;
  117.                 
  118.                 /*    Valid termination string for the meta string. */
  119.                 
  120.                 case 'd': case 'i': case 'o': case 'X': case 'x':
  121.                 case 'u': case 'c': case 's': case 'f': case 'e':
  122.                 case 'E': case 'g': case 'G': case 'p': case 'n':
  123.                 case '%':
  124.                     *currentParameterFormatString++ = currentCharValue;
  125.                     stillFormatString = 0;
  126.                     break;
  127.                 
  128.                 /*    Otherwise the character is not a valid termination
  129.                     of the meta string, so we should move the character 
  130.                     back a character so it gets read again, and 
  131.                     exit the parameter printing section of the code. */
  132.                     
  133.                 default:
  134.                     badParameter = true;
  135.                     stillFormatString = false;
  136.                     currentChar--;
  137.                     break;
  138.             
  139.             }
  140.         }
  141.         
  142.         /*    If the meta-character sequence was invalid, don’t bother calling through to 
  143.             sprintf for the actual parameter value. */
  144.         
  145.         if (badParameter) continue;
  146.  
  147.         /*    Terminate the parater format string. */
  148.         
  149.         *currentParameterFormatString++ = '\0';
  150.  
  151.         /*    Now depending on the last character in the meta-sequence, we need to 
  152.             pass a different type of argument through to sprintf to generate the
  153.             parameter string.  */
  154.         
  155.         switch (currentCharValue) {
  156.  
  157.             case 'd': case 'i': case 'o': case 'x': case 'X':
  158.             case 'u': case 'c':
  159.                 iValue = va_arg(argumentList, int);
  160.                 sprintf(parameterString, parameterFormatString, iValue);
  161.                 break;
  162.  
  163.             case 's':
  164.                 sValue = va_arg(argumentList, char *);
  165.                 sprintf(parameterString, parameterFormatString, sValue);
  166.                 break;
  167.  
  168.             case 'f': case 'e': case 'E': case 'g': case 'G':
  169.                 dValue = va_arg(argumentList, double);
  170.                 sprintf(parameterString, parameterFormatString, dValue);
  171.                 break;
  172.  
  173.             case 'p':
  174.                 pValue = va_arg(argumentList, void *);
  175.                 sprintf(parameterString, parameterFormatString, pValue);
  176.                 break;
  177.  
  178.             case 'n':
  179.                 iArgCount = va_arg(argumentList, int *);
  180.                 *iArgCount = argsWritten;
  181.                 continue;
  182.                 break;
  183.  
  184.             case '%':
  185.                 parameterString[0] = '%';
  186.                 parameterString[1] = '\0';
  187.                 break;
  188.  
  189.             default:
  190.                 parameterString[0] = '\0';
  191.                 break;
  192.         
  193.         }
  194.         
  195.         /*    If the parameter string will overflow the debug string’s kMaxDebugStringLength characters, then 
  196.             truncate it. */
  197.         
  198.         paramStringLength = strlen(parameterString);
  199.         combinedNewLength = paramStringLength + stringLength;
  200.         
  201.         if (combinedNewLength > kMaxDebugStringLength) {
  202.             paramStringLength = paramStringLength - (combinedNewLength - kMaxDebugStringLength);
  203.             parameterString[paramStringLength] = '\0';
  204.             paramTruncated = 1;
  205.         }
  206.         
  207.         /*    Add the parameter string to the debug string. */
  208.         
  209.         strcpy(debugString + stringLength + 1, parameterString);
  210.  
  211.         /*    Advance the various info as necessary. */
  212.  
  213.         stringLength += paramStringLength;
  214.         argsWritten++;
  215.     }
  216.     
  217.     /*    Make the pascal string the right length. */
  218.  
  219.     debugString[0] = stringLength;
  220.  
  221.     /*    If we did not reach the end of the format string, or we had to truncate a
  222.         parameter list, add a … to the string. */
  223.         
  224.     if ((*currentChar != 0) || paramTruncated) debugString[kMaxDebugStringLength] = '…';
  225.     
  226.     /*    Output the pascal string to the debugger. */
  227.     
  228.     DebugStr((ConstStr255Param)debugString);
  229.  
  230.     va_end(argumentList);
  231.     
  232. }    // dprintf
  233.